//
// Created by XML on 2024/1/10.
//  结构体 在C语言没有像Java等语言的class类，结构体是相当于类的概念
#include <string.h>
#include <io_utils.h>
#include <stdlib.h>

#define NAME_LEN  64

// 定义结构体 关键字struct
struct student{
    // 成员变量
    char name[NAME_LEN];
    int height;
    float weight;
    long schols;

};

// 结构体作为形参
void hiroko(struct student *stu){
    // 指针形参不能直接 *stu.height 方式访问，因为.xx运算符比指针运算符*的优先级更高，会被解析成*(stu.height)
    // 必须用（*stu).xxx访问属性
//    if((*stu).height < 180) (*stu).height = 180;
//    if((*stu).weight > 80) (*stu).weight = 80;

    // 上面这种方式可以用 -> 运算符替代
    // -> 结构体指针
    if (stu->height < 180) stu->height = 180;
    if (stu->weight > 80) stu->weight = 80;

}

//  typedef等同于为结构体取一个别名，如果没有别名的话，在初始化的时候用到结构体都需要struct关键字声明，是很繁琐的，兼容性不好
// 加别名后，在初始化的时候就可以将struct关键字省略
// 给匿名结构体设置一个别名 Student
 typedef struct  {
    char name[NAME_LEN];
} Student;

// 给指定结构体设置一个别名Student2
typedef struct student Student2 ;

void testTypedef(){
    Student student = {"lili"};
    PRINT_STRING(student.name);

    Student2  student2 = {"li",150,60,1000};
    PRINT_STRING(student2.name);
}


enum Type{
    TEXT = 10,
    IMAGE,
    VIDEO,
};

// 设置别名
typedef enum Type  Type1;

void testEnum(){
    enum Type type = TEXT;
    Type1  type1 = IMAGE;
    Type1  type2 = VIDEO;
};


int main(){
    // 初始化
    struct student lili;
    // 字符串不能直接赋值，只能拷贝的方式
    //    lili.name = "lili";
    strcpy(lili.name,"lili");
    lili.height = 175;
    lili.weight = 62.5f;
    lili.schols = 73000;

    PRINT_STRING(lili.name);
    PRINT_INT(lili.height);
    PRINT_DOUBLE(lili.weight);
    PRINT_LONG(lili.schols);

    // 初始化方式二
    struct student zs = {"zs",175,62.5f,8000};
     // &zs 指针
    hiroko(&zs);
    PRINT_STRING(zs.name);
    PRINT_INT(zs.height);
    PRINT_DOUBLE(zs.weight);
    PRINT_LONG(zs.schols);

    // 结构体开辟堆内存
    struct student *stu = malloc(sizeof(struct student) );
    strcpy(stu->name,"lisi");
    stu->height = 190;
    PRINT_STRING(stu->name);
    PRINT_INT(stu->height);
    if(stu){
        // 回收堆内存
        free(stu);
        stu =NULL;
    }

    // 结构体数组 -- 栈区
    struct student stus[5] = {{"lili",190,60.0f,6000}};
    // 向结构体数组添加元素，要先定义元素的结构体
    struct student i4 = {"mimi",165,50.0f,1};
//    stus[4] = i4;
    *(stus+4) = i4; // 指针的方式赋值
    PRINT_STRING(i4.name);
    PRINT_INT(i4.height);

    // 结构体数组 -- 堆区
    struct student *stu3 = malloc(sizeof(struct student) *5);
    *(stu3+4) = i4;
    PRINT_STRING((stu3+4)->name);
    PRINT_INT((stu3+4)->height);

    free(stu3);
    stu3 = NULL;

  testTypedef();


    return 0;
}
